Итак, у дерева есть несколько элементов. Можно считать, что есть корневые элементы, есть ветвления и есть подчиненные элементы. Общее представление можно получить посмотрев картинку внизу.

Важное место при работе с деревом занимает указатель HTREEITEM, который указывает на элемент дерева. Именно этот указатель возвращается при многих операциях с деревом, например, получение текущего элемента, получение элемента выше или подчиненных элементов. Имея этот указатель можно получить доступ ко многим операциям над элементами и свойствам элемента. Практически все функции класса CTreeCtrl используют этот указатель в качестве параметров. Но это только указатель.
У дерева есть стили, с помощью которых можно управлять аспектами его отображения. Описание каждого стиля можно посмотреть в подробностях.
TVS_HASLINES TVS_LINESATROOT TVS_HASBUTTONS TVS_EDITLABELS TVS_SHOWSELALWAYS
Стили устанавливаются при создании окна. Для этого нужно перегрузить функцию Create вида наследника от CTreeView. В последствии стили можно изменить используя функции GetWindowLong и SetWindowLong.
Для добавления пункта необходимо послать сообщение TVM_INSERTITEM, это сообщение вернет указатель HTREEITEM однозначно определяющий пункт дерева. К счастью MFC скрывает от нас подобные подробности. Давайте посмотрим как это делается. Для вставки элемента мы должны послать сообщение и указать в параметрах структуру TVINSERTSTRUCT, которая содержит структуру TVITEM. Сложно ??? Класс CTreeCtrl скрывает эти подробности позволяя вместо посылки сообщений вызывать функции. Например, вот так это выглядит.
GetTreeCtrl().InsertItem(GetTreeCtrl().GetItemText(hi),notselect,select,hit,0);
В данном коде никаких сообщений посылать не надо.
Внимание !!! Работать с элементами управления Windows нужно на основе сообщений. Классы ....CTRL заменяют посылку сообщений вызывами функций классов. Это значительно упрощает программирование. Но вероятно и ведет к усечению ряда возможностей. Еще раз посылка сообщений заменена вызовом функции. Это очень важно для понимания работы многих элементов управления. Вот так реализована подмена сообщения.
_AFXCMN_INLINE BOOL CTreeCtrl::GetItem(TVITEM* pItem) const
{ ASSERT(::IsWindow(m_hWnd)); return (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)pItem); }
С этим понятно. Теперь надо разобраться, как получить информацию от элемента дерева. Если без MFC, то нужно послать сообщение, а с MFC вызвать функцию GetItem, что одно и тоже. Вот она.
BOOL GetItem( TVITEM* pItem );
В эту функцию передается адрес структуры TVITEM, вот её описание.
typedef struct tagTVITEM
{
UINT mask;
HTREEITEM hItem;
UINT state;
UINT stateMask;
LPTSTR pszText;
int cchTextMax;
int iImage;
int iSelectedImage;
int cChildren;
LPARAM lParam;
} TVITEM, FAR *LPTVITEM;
Что здесь главное, ну во-первых, hItem должен указывать на элемент дерева, который существует. Дальше mask, а вот здесь указывается какие данные мы хотим извлечь.
Обратите внимание на то, что название это LPTSTR. То есть нужен буфер, в который она поместится. Вот пример кода извлекающего имя активного элемента.
void CLeftView::OnTest()
{
HTREEITEM hi;
hi=GetTreeCtrl().GetSelectedItem();
if (hi!=NULL)
{
TV_ITEM pItem; // структура
char szBuffer[20]; // буфер для названия
memset(&pItem,0,sizeof(pItem)); // обнуляем структуру
pItem.hItem=hi; // этого элемента информацию мы хотим получить
pItem.mask= TVIF_TEXT ; // тип получаемой информации
pItem.pszText = szBuffer; // куда вернуть
pItem.cchTextMax=19; // размер буфера = размер char-1 для завершения строки
GetTreeCtrl().GetItem(&pItem); // получить информацию
AfxMessageBox(pItem.pszText);
}
else AfxMessageBox("Not Selected Item");
}
Итак, воспользовавшись этим можно получить всю информацию о элементе дерева и перевести указатель HTREEITEM в реальную структуру TV_ITEM.